#pragma once
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <memory>
#include <utility>
#include <asio.hpp>
#include <mutex>
#include <unordered_map>
#include <vector>
#include <string>
#include <queue>
#include <ctime>
#include <atomic>
#include <chrono>
#include "define.h"

class ChannelManager;
class Channel : public std::enable_shared_from_this<Channel>
{
public:
	Channel(ChannelManager*pChannelMgr, asio::ip::tcp::socket socket,
				asio::io_context *pIoContext, ChannalType nChannalType);
	~Channel();
	int GetChannelID() { return m_nChannelID; }
	void SetChannelID(int32_t nChannelID) { m_nChannelID = nChannelID; }
	void StartRead();
	bool IsMe(const std::string & strHost, int32_t sPort)
	{
		return m_strRemoteIp == strHost && m_uRemotePort == sPort;
	}
	// 向其他请求握手
	void DoReqShakeHand();
	void SendMsg(const char*pData, size_t nDataLen);
	void write(char *data, std::size_t length);
	std::string RemoteIp() 
	{
		return m_strRemoteIp;
	}
	std::string remote_ip() { return m_Socket.remote_endpoint().address().to_string(); }
	int32_t remote_port() { return m_uRemotePort; }
	uint64_t SendTimes() { return m_nSendTimes; }
	uint64_t RecvTimes() { return m_nRecvTimes; }
	uint64_t SendBytes() { return m_nSendBytes; }
	uint64_t RecvBytes() { return m_nRecvBytes; }
	time_t CreateTime() { return m_tCreateTime; }

private:
	void DoReadHead();
	void DoReadBody();
	void DoWrite();
	void DoClose();
	void PumpHeartBeat();
	void HeartBeat();
	void OnReceive();
	void OnRecvShakeHandReq();
	void OnRecvShakeHandRsp();
	//************************************
	// Method:    TimeNow
	// Author:    zhaoyao
	// DATE:      2021/07/27 17:48:01
	// Brief:     获取格林威治时间当前秒数
	//************************************
	int64_t TimeNow();

	asio::io_context *m_pIoContext;
	ChannelManager *m_pChannelMgr;
	asio::ip::tcp::socket m_Socket;
	NetHead m_head;
	std::string m_body;
	time_t m_tCreateTime; // 回话创建时间
	uint64_t m_nSendTimes;
	uint64_t m_nRecvTimes;
	uint64_t m_nSendBytes;
	uint64_t m_nRecvBytes;
	uint64_t m_nLastActiveTime; // 上次活动时间

	struct Node
	{
		char *pData;
		std::size_t nLen;
	};

	std::string m_strRemoteIp;//接入方ip地址
	int32_t m_uRemotePort;//接入方端口
	std::queue<Node> m_dataQueue;
	bool m_bSending;
	int32_t m_nChannelID;
	ChannalType m_channalType;
	asio::steady_timer m_timerHeartBeat; // 心跳包定时器
	
};
